import json
from datetime import datetime

from apiview.views import View
from django.http.response import JsonResponse
from django.shortcuts import render
from django_redis import get_redis_connection
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.hourses.hourseserializer import AreaSerializer, HouseSerializer
from apps.hourses.models import Area, House, HouseImage
from apps.orders.models import Order
from apps.users.models import User
from utils.Audit_comment import Audit, Auditaaa
from utils.es_search import search, index
from utils.login_required import LoginRequiredJSONMixin
from utils.send_message import upload, url

# Create your views here.

from django.views.decorators.cache import cache_page

redis_conn = get_redis_connection()


# 地址列表的获取
class AreasView(APIView):
    def get(self, request):
        # 使用序列化器进行获取数据
        # redis_data = redis_conn.get('areas_data')
        # if redis_data:
        # data = json.loads(redis_data)
        # return Response({"errno": "0", "errmsg": "获取成功", "data": data})

        data = Area.objects.all()
        obj = AreaSerializer(instance=data, many=True)
        aa = obj.data
            # redis_conn.set('areas_data', json.dumps(aa), ex=1)
        return Response({"errmsg": "获取成功", "errno": "0", "data": aa})


# 房源发布以及房源搜索
class AreaPostView(APIView):
    def post(self, request):
        # 获取前端数据
        data = request.data
        title = data.get('title')
        price = data.get('price')
        area_id = data.get('area_id')
        room_count = data.get('room_count')
        acreage = data.get('acreage')
        address = data.get('address')
        unit = data.get('unit')
        capacity = data.get('capacity')
        beds = data.get('beds')
        deposit = data.get('deposit')
        min_days = data.get('min_days')
        max_days = data.get('max_days')
        facility = data.get('facility')
        res = Audit(title)
        # 进行判断   所评论内容是否违反审核标准
        # 获取参数进行判断
        if res.get('conclusion') != '合规':
            return Response({'errno': 400, 'errmsg': '标题不可以包含违规内容'})
        if not len(title) <= 10:
            return Response({'errno': 400, 'errmsg': '标题只能小于10个字符'})
        if int(price) < 0:
            return Response({'errno': 400, 'errmsg': '价格不能小于0'})
        if not area_id:
            return Response({'errno': 400, 'errmsg': '地址不能为空'})
        if int(deposit) < 0:
            return Response({'errno': 400, 'errmsg': '押金不能小于0'})
        if int(min_days) < 0:
            return Response({'errno': 400, 'errmsg': '最少租期不能为负'})
        if int(max_days) < 0:
            return Response({'errno': 400, 'errmsg': '最多租期不能为负'})
        try:
            # 获取用户
            user = request.user
            house = House.objects.create(
                user=user,
                title=title,
                price=price,
                area_id=area_id,
                room_count=room_count,
                acreage=acreage,
                unit=unit,
                capacity=capacity,
                address =address,
                beds=beds,
                deposit=deposit,
                min_days=min_days,
                max_days=max_days,
            )
            body = {
                "id": house.id,
                "title": house.title,
                "order_count": house.order_count,
                "room_count": house.room_count,
                "price": house.price,
                "area_id": house.area.id,
                "name": house.area.name,
                "avatar": url +str(house.user.avatar),
                "address": house.address,
                "min_days": house.min_days,
                "create_time": house.create_time,
                "index_image_url": url + str(house.index_image_url),
            }
            index(body, 'house', 'index', house.id)
            house.facility.set(facility)
            redis_conn.delete('house_index_data')
            return Response({
                "errno": "0",
                "errmsg": "发布成功",
                "data": {
                    "house_id": house.id
                }
            })
        except:
            return JsonResponse({'errno': 400, 'errmsg': '发布房源失败'})
    # def get(self,request):
    #     data  = request.GET
    #     aid = data.get("aid")   #区域id
    #     sd = data.get("sd")        #开始日期
    #     ed = data.get("ed")         #结束时间
    #     sk = data.get("sk")        #排序方式
    #     p = data.get("p")       #页数
    #     """根据区域id 查找房源"""
    #     house = House.objects.filter(area_id=aid).all()
    #     area = Area.objects.filter(id=aid).first()
    #     houses = []
    #     for i in house:
    #        datetime1 = datetime.strptime(sd, "%Y-%m-%d")
    #        datetime2 = datetime.strptime(ed, "%Y-%m-%d")
    #        difference = datetime2 - datetime1
    #        date = difference.days
    #             # 根据hous里面的用户id找到用户的头像
    #        user = User.objects.filter(id=i.user_id).first()
    #        user_image = url + str(user.avatar)
    #        houses.append({
    #             "address":str(i.address),
    #             "area_name":str(area.name),
    #             "ctime":str(i.create_time),
    #             "house_id":str(i.id),
    #             "img_url":url+str(i.index_image_url),
    #             "order_count":str(i.order_count),
    #             "price":str(i.price),
    #             "room_count":str(i.room_count),
    #             "title":str(i.title),
    #             "user_avatar":str(user_image),
    #             "min_days":str(i.min_days),
    #             "area_id":str(i.area_id)
    #         })
    #     # #         将房屋数据存储到elasticsearch中
    #     # for data in houses:
    #     #     es.index(index="house_index",body=data)
    #
    #     #        如果total_page是2的话 返回的是两条一样的数据  所以看一下houses里面有几条数据，就让它返回几
    #     num  = len(houses)
    #     return JsonResponse({"data": {"houses": houses,"total_page": num},"errmsg": "请求成功","errno": "0"})
        # return JsonResponse({"errno":0,"errmsg":"OK"})
    # def get(self, request):
    #     # 从前端中提取参数
    #     aid = request.GET.get('aid')
    #     sd = request.GET.get('sd')
    #     ed = request.GET.get('ed')
    #     sk = request.GET.get('sk')
    #     p = request.GET.get('p')
    #     data = []
    #     if sd == '' and ed == '':
    #         if aid != '':
    #             if sk == 'booking':
    #                 house = House.objects.filter(area_id=aid).all().order_by('-order_count')
    #             elif sk == 'price-inc':
    #                 house = House.objects.filter(area_id=aid).all().order_by('price')
    #             elif sk == 'price-des':
    #                 house = House.objects.filter(area_id=aid).all().order_by('-price')
    #             else:
    #                 house = House.objects.filter(area_id=aid).all().order_by('-create_time')
    #         else:
    #             if sk == 'booking':
    #                 house = House.objects.all().order_by('-order_count')
    #             elif sk == 'price-inc':
    #                 house = House.objects.all().order_by('price')
    #             elif sk == 'price-des':
    #                 house = House.objects.all().order_by('-price')
    #             else:
    #                 house = House.objects.all().order_by('-create_time')
    #         for i in house:
    #             data.append({
    #                 'address': i.address,
    #                 'area_name': i.area.name,
    #                 'ctime': i.create_time,
    #                 'house_id': i.id,
    #                 'img_url': url + str(i.index_image_url),
    #                 'order_count': i.order_count,
    #                 'price': i.price,
    #                 'room_count': i.room_count,
    #                 'title': i.title,
    #                 'user_avatar': url + str(i.user.avatar),
    #             })
    #     elif ed == '':
    #         if sk == 'booking':
    #             house = House.objects.filter(area_id=aid, create_time__lte=sd).all().order_by('-order_count')
    #         elif sk == 'price-inc':
    #             house = House.objects.filter(area_id=aid, create_time__lte=sd).all().order_by('price')
    #         elif sk == 'price-des':
    #             house = House.objects.filter(area_id=aid, create_time__lte=sd).all().order_by('-price')
    #         else:
    #             house = House.objects.filter(area_id=aid, create_time__lte=sd).all().order_by('-create_time')
    #         for i in house:
    #             data.append({
    #                 'address': i.address,
    #                 'area_name': i.area.name,
    #                 'ctime': i.create_time,
    #                 'house_id': i.id,
    #                 'img_url': url + str(i.index_image_url),
    #                 'order_count': i.order_count,
    #                 'price': i.price,
    #                 'room_count': i.room_count,
    #                 'title': i.title,
    #                 'user_avatar': url + str(i.user.avatar),
    #             })
    #     else:
    #         # 计算入住天数
    #         datetime1 = datetime.strptime(sd, "%Y-%m-%d")
    #         datetime2 = datetime.strptime(ed, "%Y-%m-%d")
    #         difference = datetime2 - datetime1
    #         # 获取搜索的房源
    #         if sk == 'booking':
    #             house = House.objects.filter(area_id=aid, create_time__lte=sd, min_days__lte=difference.days).all().order_by('-order_count')
    #         elif sk == 'price-inc':
    #             house = House.objects.filter(area_id=aid, create_time__lte=sd, min_days__lte=difference.days).all().order_by('price')
    #         elif sk == 'price-des':
    #             house = House.objects.filter(area_id=aid, create_time__lte=sd, min_days__lte=difference.days).all().order_by('-price')
    #         else:
    #             house = House.objects.filter(area_id=aid, create_time__lte=sd, min_days__lte=difference.days).all().order_by('-create_time')
    #         print(house)
    #         # 把房源信息保存到data里面
    #         for i in house:
    #             order = Order.objects.filter(house=i.id, begin_date__lte=sd, end_date__gte=ed).first()
    #             if order != None:
    #                 if order.status != 6:
    #                     continue
    #             data.append({
    #                 'address': i.address,
    #                 'area_name': i.area.name,
    #                 'ctime': i.create_time,
    #                 'house_id': i.id,
    #                 'img_url': url + str(i.index_image_url),
    #                 'order_count': i.order_count,
    #                 'price': i.price,
    #                 'room_count': i.room_count,
    #                 'title': i.title,
    #                 'user_avatar': url + str(i.user.avatar),
    #             })
    #     return JsonResponse({'errno': '0', 'errmsg': '请求成功', 'data': {'houses': data, 'total_page': p}})

    # 房屋数据搜索
    def get(self, request):
        # 从前端中提取参数
        aid = request.GET.get('aid')
        sd = request.GET.get('sd')
        ed = request.GET.get('ed')
        sk = request.GET.get('sk')
        p = request.GET.get('p')
        # 获取搜索的房源的排序
        if sk == 'booking':
            order_by = "order_count"
            sort = "desc"
        elif sk == 'price-inc':
            order_by = "price"
            sort = "asc"
        elif sk == 'price-des':
            order_by = "price"
            sort = "desc"
        else:
            order_by = "create_time"
            sort = "desc"
        # 把房源信息保存到data_house里面
        data_house = []
        if sd == '' and ed == '':
            if aid != '':
                # 使用 Elasticsearch 进行搜索所有房屋信息
                body = {
                    "query": {"bool": {"must": [{"term": {"area_id": aid}}, ]}},
                    "sort": [{order_by: {"order": sort}}]
                }
                data = search(body, 'house', 'search')
            else:
                # 使用 Elasticsearch 进行搜索aid地区的房屋信息
                body = {
                    "query": {"match_all": {}},
                    "sort": [{order_by: {"order": sort}}]
                }
                data = search(body, 'house', 'search')
            for i in data:
                data_house.append({
                    'address': i.get('address'),
                    'area_name': i.get('name'),
                    'ctime': i.get('create_time'),
                    'house_id': i.get('id'),
                    'img_url': url + str(i.get('index_image_url')),
                    'order_count': i.get('order_count'),
                    'price': i.get('price'),
                    'room_count': i.get('room_count'),
                    'title': i.get('title'),
                    'user_avatar': url + str(i.get('avatar')),
                })
# 使用 Elasticsearch 进行搜索aid地区和入住日期之前发布的房屋信息
        elif ed == '':
            if aid != '':
                body = {
                    "query": {"bool": {"must": [
                        {"term": {"area_id": aid}},
                        {"range": {"create_time": {"lte": sd}}},
                    ]}},
                    "sort": [{order_by: {"order": sort}}]
                }
            else:
# 使用 Elasticsearch 进行搜索入住日期之前发布的房屋信息
                body = {
                    "query": {"bool": {"must": [
                        {"range": {"create_time": {"lte": sd}}},
                    ]}},
                    "sort": [{order_by: {"order": sort}}]
                }
            data = search(body, 'house', 'search')
            for i in data:
# 使用 Elasticsearch 进行搜索入住日期没被预定的房屋信息
                body = {
                    "query": {"bool": {"must": [
                        {"term": {"house_id": i.get('id')}},
                        {"range": {"begin_date": {"gte": sd}}},
                    ]}}, }
                order = search(body, 'order', 'search')
                # 判断该房屋是否被预定
                if order != []:
               # 判断被预定的房屋是否被拒单或者取消
                    for i in order:
                        if i.get('status') != '6' or i.get('status') != '5':
                            continue
                else:
                    data_house.append({
                        'address': i.get('address'),
                        'area_name': i.get('name'),
                        'ctime': i.get('create_time'),
                        'house_id': i.get('id'),
                        'img_url': url + str(i.get('index_image_url')),
                        'order_count': i.get('order_count'),
                        'price': i.get('price'),
                        'room_count': i.get('room_count'),
                        'title': i.get('title'),
                        'user_avatar': url + str(i.get('avatar')),
                    })
        else:
            # 计算入住天数
            datetime1 = datetime.strptime(sd, "%Y-%m-%d")
            datetime2 = datetime.strptime(ed, "%Y-%m-%d")
            difference = datetime2 - datetime1
            # 使用 Elasticsearch 进行搜索房屋信息
            if aid == '':
                # 使用 Elasticsearch 进行搜索房屋信息
                body = {
                    "query": {"bool": {"must": [
                        {"range": {"create_time": {"lte": sd}}},
                        {"range": {"min_days": {"lte": difference.days}}}
                    ]}},
                    "sort": [{order_by: {"order": sort}}]
                }
            else:
                body = {
                    "query": {"bool": {"must": [
                        {"term": {"area_id": aid}},
                        {"range": {"create_time": {"lte": sd}}},
                        {"range": {"min_days": {"lte": difference.days}}}
                    ]}},
                    "sort": [{order_by: {"order": sort}}]
                }
            data = search(body, 'house', 'search')
            for i in data:
                # 使用 Elasticsearch 进行搜索该时间段被预定的房屋信息
                body = {
                    "query": {"bool": {"must": [
                        {"term": {"house_id": i.get('id')}},
                        {"range": {"begin_date": {"lte": sd}}},
                        {"range": {"end_date": {"gte": ed}}}
                    ]}}, }
                order = search(body, 'order', 'search')
                # 判断该房屋是否被预定
                if order != []:
                    # 判断被预定的房屋是否被拒单或者取消
                    for i in order:
                        if i.get('status') != '6' or i.get('status') != '5':
                            continue
                else:
                    data_house.append({
                        'address': i.get('address'),
                        'area_name': i.get('name'),
                        'ctime': i.get('create_time'),
                        'house_id': i.get('id'),
                        'img_url': url + str(i.get('index_image_url')),
                        'order_count': i.get('order_count'),
                        'price': i.get('price'),
                        'room_count': i.get('room_count'),
                        'title': i.get('title'),
                        'user_avatar': url + str(i.get('avatar')),
                    })
        return JsonResponse({'errno': '0', 'errmsg': '请求成功', 'data': {'houses': data_house, 'total_page': p}})
    #

# 房源的获取数据
class HouseView(APIView):
    def get(self, request):
        # redis_data = redis_conn.get('house_data_%s' % request.user.id)
        # if redis_data:
        # data = json.loads(redis_data)
        # return Response({"errno": "0", "errmsg": "获取成功", "data": {'houses': data}})
        data = House.objects.filter(user=request.user)
        # 进行序列化器，进行获取数据
        obj = HouseSerializer(instance=data, many=True)
        # redis_conn.set('house_data_%s' % request.user.id, json.dumps(obj.data), ex=1)
        return Response(({"errmsg": "获取成功", "errno": "0", "data": {'houses': obj.data}}))


# 发布房源后进行上传房源图片
class UploadhouseView(LoginRequiredJSONMixin, APIView):
    def post(self, request, house_id):
        house_image = request.data.get('house_image')
        res = Auditaaa(house_image)
        # 进行判断   所评论内容是否违反审核标准
        # 获取参数进行判断
        if res.get('conclusion') != '合规':
            return Response({'errno': 400, 'errmsg': '房屋图片不可以包含违规色情画面'})
        aa = House.objects.get(id=house_id)
        ret, info = upload(house_image)
        if info.status_code != 200:
            return Response('上传失败', status=201)
        aa.index_image_url = ret.get('key')
        aa.save()
        res = {
            "data": {
                "url": url + str(aa.index_image_url)
            },
            "errno": "0",
            "errmsg": "图片上传成功"
        }
        return Response(res)


# 主页的获取数据
class HouseIndexView(APIView):
    def get(self, request):
        # redis_data = redis_conn.get('house_index_data')
        # if redis_data:
        #     data = json.loads(redis_data)
        #     return Response({"errno": "0", "errmsg": "获取成功", "data": data})
        data = House.objects.all()
        # 进行序列化器，进行获取数据
        obj = HouseSerializer(instance=data, many=True)
        # redis_conn.set('house_index_data', json.dumps(obj.data), ex=1)
        return Response(({"errmsg": "获取成功", "errno": "0", "data": obj.data}))


# 房屋的详情页面
class HouseDetailView(APIView):
    def get(self, request, house_id):
        if redis_conn.get('house_detail_%s'):
            data = json.loads(redis_conn.get('house_detail_%s'))
            return Response({"errno": "0", "errmsg": "获取成功", "data": data})
        # 进行查询房屋id
        house = House.objects.get(id=house_id)
        # 进行查询用户信息
        user = User.objects.get(id=house.user.id)
        # 进行一个图片的查询
        image = HouseImage.objects.filter(house_id=house_id)
        image_list = []
        # 获取房源图片的一个显示
        for i in image:
            image_list.append(url + i.url)
        image_list.append(
            url + house.index_image_url
        )
        facility_list = []
        # 进行外键的一个获取房源数据
        for i in house.facility.all():
            facility_list.append(i.id)
        res = json.dumps(
            {
                "data": {
                    "house": {
                        "acreage": house.acreage,
                        "address": house.address,
                        "beds": house.beds,
                        "capacity": house.capacity,
                        "comments": [
                            {
                                "comment": None,
                                "ctime": None,
                                "user_name": None,
                            }
                        ],
                        "deposit": house.deposit,
                        "facilities":
                            facility_list
                        ,
                        "hid": house.id,
                        "img_urls":
                            image_list,
                        "max_days": house.max_days,
                        "min_days": house.min_days,
                        "price": house.price,
                        "room_count": house.room_count,
                        "title": house.title,
                        "unit": house.unit,
                        "user_avatar": url + str(house.user.avatar),
                        "user_id": user.id,
                        "user_name": user.username
                    },
                    "user_id": request.user.id
                },
                "errmsg": "OK",
                "errno": "0"
            }
        )
        redis_conn.set('house_detail_%s' % house_id, res, ex=24 * 60 * 60)
        return Response(json.loads(res))
